/******************** (C) COPYRIGHT 2013 STMicroelectronics ********************
* File Name          : LSM9DS1.h
* Author             : MSH Application Team
* Version            : $Revision:$
* Date               : $Date:$
* HISTORY:
* Date			| Modification			| Author
* 21/08/2013		| Initial Revision		| Alberto Zancanato
* 22/10/2015            | Abstract I/O Mode, clean      | Federico Rizzardini
*
********************************************************************************
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
*
* THIS SOFTWARE IS SPECIFICALLY DESIGNED FOR EXCLUSIVE USE WITH ST PARTS.
*
*******************************************************************************/

/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __LSM9DS1_H
#define __LSM9DS1_H

/* Includes ------------------------------------------------------------------*/
#include "stm32f10x.h"
#include "i2c_mems.h"
#include "spi_mems.h"
/* Exported types ------------------------------------------------------------*/
/* Exported constants --------------------------------------------------------*/

#define BIT(x) ( 1<<(x) )

#define VER                             	0
#define DEV                             	1
#define ZOFF                            	2
#define ZON                             	4
#define START                           	5
#define STOP                            	6
#define R                               	7
#define W                               	8
#define DEBUG                           	9
#define DEBUGA                           	10
#define DEBUGG                           	11
#define DEBUGM                           	12


/* ACC FIFO CONFIGURATIONS */
#define FIFO_BYPASS                             30
#define FIFO_STREAM                             31
#define FIFO_MODE                               32
#define FIFO_STOP_TRIG	                        33
#define FIFO_READ				34
#define FIFO_RUN				35
#define FIFO_BYPASS_TO_STREAM			36
#define FIFO_D_STREAM				38

#define MR                              	15
#define MW                              	16
#define GR                              	17
#define GW                              	18
#define LIST                            	19
#define SINGLE                          	20
#define ECHOON                          	21
#define ECHOOFF                         	22
#define LISTDEV                         	23
#define DBRESET                         	24
#define RM                               	39 /* Read/Write Multiple regs */
#define WM                               	40
#define GRM                                     41
#define GWM                                     42
#define MRM                                     43
#define MWM                                     44

#define OUT_X_L					0x28
#define OUT_X_H					0x29
#define OUT_Y_L					0x2A
#define OUT_Y_H					0x2B
#define OUT_Z_L					0x2C
#define OUT_Z_H					0x2D

#define A_DATAREADY_BIT				A_STATUS_REG_ZYXDA

/* FIFO REGISTERS */
#define FIFO_CONTROL				0x2E
#define FIFO_CONTROL_TRIG			BIT(5)
#define FIFO_CONTROL_WTMSAMP            	(BIT(4) | BIT(3) | BIT(2) | BIT(1) | BIT(0))

#define DEF_FIFO_CTRL_BYPASS           	        0x00
#define DEF_FIFO_CTRL_FIFO_MODE         	BIT(5)
#define DEF_FIFO_CTRL_STREAM_TO_FIFO		(BIT(6) | BIT(5))
#define DEF_FIFO_CTRL_BYPASS_TO_STREAM		BIT(7)
#define DEF_FIFO_CTRL_STREAM                    (BIT(7) | BIT(6))

#define FIFO_SOURCE                     	0x2F
#define FIFO_SOURCE_SAMPLES             	(BIT(4) | BIT(3) | BIT(2) | BIT(1) | BIT(0))
#define FIFO_SOURCE_EMPTY               	BIT(5)
#define FIFO_SOURCE_OVRN                	BIT(6)
#define FIFO_SOURCE_WTM                 	BIT(7)

#define CTRL_REG6_XL				0x20 
#define CTRL_REG6_XL_DEFAULT               	0

#define CTRL_REG1_G				0x10
#define CTRL_REG1_G_DEFAULT               	0

#define CTRL_REG9				0x23
#define CTRL_REG9_DEFAULT               	0

#define A_STATUS_REG				0x17
#define A_STATUS_REG_ZYXDA			0   // 0	:	a new set of data is not yet avvious one
                                                    // 1	:	a new set of data is available 

#define INT_GEN_SRC_XL                        	0x26
#define INT_SRC_IA_XL                     	BIT(6)

/* I2C Addresses */
#define ACC_GYRO_ADDRESS                     	0xD6
#define MAG_ADDRESS                     	0x3C

/* SPI CS */
#define CS_ACC_GYR                              0
#define CS_MAG                                  1

/* Gyro Defines */
#define GYRO_STATUS_REG                 	0x27
#define GYRO_DATAREADY_BIT              	1

#define OUT_TEMP_L			        0x15
#define OUT_TEMP_H			        0x16
#define STATUS_REG			        0x17
#define OUT_GX_L				0x18
#define OUT_GX_H				0x19
#define OUT_GY_L				0x1A
#define OUT_GY_H				0x1B
#define OUT_GZ_L				0x1C
#define OUT_GZ_H				0x1D

/* Mag Defines */
#define CTRL_REG1_M				0x20
#define CTRL_REG3_M				0x22
#define STATUS_REG_M				0x27
#define OUT_MX_L				0x28
#define OUT_MX_H				0x29
#define OUT_MY_L				0x2A
#define OUT_MY_H				0x2B
#define OUT_MZ_L				0x2C
#define OUT_MZ_H				0x2D


#define M_DATAREADY_BIT				3

#define GYROSCOPE				0x00
#define ACCELEROMETER				0x01
#define MAGNETOMETER				0x02

#define GYRO_IS_FASTEST                 	GYROSCOPE
#define ACC_IS_FASTEST                  	ACCELEROMETER
#define MAG_IS_FASTEST                  	MAGNETOMETER

/* GPIOs Push/Pull */

#define DEN_G_GPIO_PORT				HP_GPIO_PORT
#define DEN_G_GPIO_CLK				HP_GPIO_CLK
#define DEN_G_GPIO_PIN				HP_GPIO_PIN

#define CS_A_GPIO_PORT				PD_GPIO_PORT
#define CS_A_GPIO_CLK				PD_GPIO_CLK
#define CS_A_GPIO_PIN                 		PD_GPIO_PIN

#define DEN_GON DEN_G_GPIO_PORT->BSRR = 	DEN_G_GPIO_PIN
#define DEN_GOFF DEN_G_GPIO_PORT->BRR = 	DEN_G_GPIO_PIN
#define DEN_GTOGGLE DEN_G_GPIO_PORT->ODR ^=     DEN_G_GPIO_PIN

#define CS_AON CS_A_GPIO_PORT->BSRR =		CS_A_GPIO_PIN
#define CS_AOFF CS_A_GPIO_PORT->BRR =		CS_A_GPIO_PIN
#define CS_ATOGGLE CS_A_GPIO_PORT->ODR ^=	CS_A_GPIO_PIN

#define INT3_SRC                        	0x31
#define INT3_SRC_IA                     	BIT(6)

/* Gyro Registers */
#define G_WHO_AM_I				0x0F

/* Control Register 1 */
#define G_CTRL_REG1				CTRL_REG1_G 
#define G_CTRL_REG1_DEFAULT			0


/* Status Register */
#define G_STATUS_REG				GYRO_STATUS_REG
#define G_STATUS_REG_ZYXDA			GYRO_DATAREADY_BIT   
                                                // 0	:	a new set of data is not yet avvious one
                                                // 1	:	a new set of data is available 

/* INT1_SRC */
#define G_INT1_SRC				0x14
#define G_INT1_SRC_IA				BIT(6)

#define CTRL_REG9_FIFO_EN			BIT(1)
#define CTRL_REG9_STOP_ON_WTM			BIT(0)

#define INT2_CTRL				0x0D
#define INT2_DRDY_G				BIT(1)
#define INT2_DRDY_XL				BIT(0)

#define INT1_CTRL				0x0C
#define INT1_DRDY_G				BIT(1)
#define INT1_DRDY_XL				BIT(0)

/* I/O with device */
enum io_device {
  USE_SPI = 0,
  USE_I2C = 1
};

static inline void read_dev_reg(uint8_t *data, uint8_t slv_addr, uint8_t address, enum io_device mode, uint8_t cs_num)
{
  switch (mode) {
  default:
  case USE_I2C:
    I2Cx_Read(data, slv_addr, address, 1);
    break;

  case USE_SPI:
    *data = SPI_Mems_Read_Reg_CS(cs_num, address);
    break;
  }
}

static inline void read_dev_mem(uint8_t *data, uint8_t slv_addr, uint8_t address, uint16_t len, enum io_device mode, uint8_t cs_num)
{
  switch (mode) {
  default:
  case USE_I2C:
    I2Cx_Read(data, slv_addr, address | 0x80, len);
    break;

  case USE_SPI:
    /* Increment in Multi_Read */
    if (cs_num == CS_MAG)
      address += 0x40;
    SPI_Read_MultiData_Raw_CS(cs_num, address | 0x80, len, data);
    break;
  }
}


static inline void write_dev_reg(uint8_t data, uint8_t slv_addr, uint8_t address, enum io_device mode, uint8_t cs_num)
{
  switch (mode) {
  default:
  case USE_I2C:
    I2Cx_Write(&data, slv_addr, address, 1);
    break;

  case USE_SPI:
    SPI_Mems_Write_Reg_CS(cs_num, address, data);
    break;
  }
}

/* Exported functions --------------------------------------------------------*/
void lsm6ds0_AppTick(void);

#endif /* __LSM9DS1_H */

/******************* (C) COPYRIGHT 2013 STMicroelectronics *****END OF FILE****/